﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using TinyPinyin;

namespace gptDataType.Helper
{
    public class GenerateUniqueVariableName
    {
        // 用于记录已经生成的变量名及其出现次数  
        private Dictionary<string, int> _generatedNames = new Dictionary<string, int>();

        /// <summary>  
        /// 对输入字符串进行转换：  
        /// 1. 将连续的中文字符转换为拼音，并转换为驼峰形式（内部各段首字母大写的风格，后续全小写）。  
        /// 2. 英文部分保持原样。  
        /// 3. 使用下划线连接各段。  
        /// 4. 替换掉特殊字符，使最终变量名只包含字母、数字和下划线，并保证变量名符合 C 语言变量命名规范（首字母为字母或下划线）。  
        /// 5. 最终生成的变量名首字母大写，且已保证唯一性（重复时后面添加 _数字 后缀）。  
        /// </summary>  
        public string Convert(string input)
        {
            // 分段存放各个部分：中文段或英文段  
            var segments = new List<string>();
            // 中文拼音片段，逐个汉字转换后的拼音集合  
            var chineseBuffer = new List<string>();
            // 英文或非中文字符片段  
            var englishBuffer = new StringBuilder();

            // 遍历每个字符  
            foreach (char c in input)
            {
                if (IsChinese(c))
                {
                    // 如果之前有英文字符，则先处理英文部分  
                    if (englishBuffer.Length > 0)
                    {
                        segments.Add(englishBuffer.ToString());
                        englishBuffer.Clear();
                    }
                    // 使用 TinyPinyin 库转换当前中文字符为拼音（转换结果默认为小写）  
                    string pinyin = PinyinHelper.GetPinyin(c.ToString()).ToLower();
                    chineseBuffer.Add(pinyin);
                }
                else
                {
                    // 当遇到非中文字符时，先把累积的中文拼音转换后加入分段列表  
                    if (chineseBuffer.Count > 0)
                    {
                        segments.Add(ConvertToCamel(chineseBuffer));
                        chineseBuffer.Clear();
                    }
                    // 直接追加英文或其他字符  
                    englishBuffer.Append(c);
                }
            }
            // 将残留的缓冲区内容处理后加入分段  
            if (chineseBuffer.Count > 0)
            {
                segments.Add(ConvertToCamel(chineseBuffer));
            }
            if (englishBuffer.Length > 0)
            {
                segments.Add(englishBuffer.ToString());
            }

            // 使用下划线连接所有分段  
            string variableName = string.Join("_", segments);

            // 替换特殊字符，只允许字母、数字、下划线，并确保首字符为字母或下划线  
            variableName = SanitizeVariableName(variableName);

            // 将首字母大写（符合要求的风格）  
            variableName = Capitalize(variableName);

            // 生成唯一变量名：如果名称已存在，则在末尾附加 _数字 后缀  
            if (_generatedNames.ContainsKey(variableName))
            {
                int count = _generatedNames[variableName];
                _generatedNames[variableName] = count + 1;
                variableName = variableName + "_" + count;
            }
            else
            {
                _generatedNames[variableName] = 1;
            }

            return variableName;
        }

        /// <summary>  
        /// 判断字符是否为中文，简单判断 Unicode 范围（\u4e00 ~ \u9fff）。  
        /// </summary>  
        private bool IsChinese(char c)
        {
            return c >= '\u4e00' && c <= '\u9fff';
        }

        /// <summary>  
        /// 将连续的中文拼音（已转换为小写形式）转成驼峰格式：  
        /// 第一个拼音全部小写，后续拼音单词首字母大写，其余小写。  
        /// 例如：["zhang", "shan"] → "zhangShan"  
        /// </summary>  
        private string ConvertToCamel(List<string> syllables)
        {
            if (syllables.Count == 0)
                return string.Empty;

            StringBuilder sb = new StringBuilder();
            // 第一个拼音直接全部小写  
            sb.Append(syllables[0].ToLower());
            // 后续单词首字母大写，其余保持小写  
            for (int i = 1; i < syllables.Count; i++)
            {
                if (!string.IsNullOrEmpty(syllables[i]))
                {
                    sb.Append(char.ToUpper(syllables[i][0]));
                    if (syllables[i].Length > 1)
                        sb.Append(syllables[i].Substring(1).ToLower());
                }
            }
            return sb.ToString();
        }

        /// <summary>  
        /// 替换变量名中的特殊字符，只允许字母、数字和下划线，并确保变量名的首字符为字母或下划线。  
        /// </summary>  
        private string SanitizeVariableName(string name)
        {
            StringBuilder sb = new StringBuilder();
            foreach (char c in name)
            {
                // 判断字符是否为字母、数字或下划线  
                if (char.IsLetterOrDigit(c) || c == '_')
                {
                    sb.Append(c);
                }
                else
                {
                    // 不符合要求的字符统一替换为下划线  
                    sb.Append('_');
                }
            }
            string sanitized = sb.ToString();
            // 若首字符不是字母或下划线，则在最前面添加下划线  
            if (sanitized.Length > 0 && !char.IsLetter(sanitized[0]) && sanitized[0] != '_')
            {
                sanitized = "_" + sanitized;
            }
            return sanitized;
        }

        /// <summary>  
        /// 将字符串的首字母转换为大写。  
        /// </summary>  
        private string Capitalize(string s)
        {
            if (string.IsNullOrEmpty(s)) return s;
            return char.ToUpper(s[0]) + s.Substring(1);
        }
    }
}
